package org.jim.server.command;

import cn.hutool.core.annotation.AnnotationUtil;
import com.huiyun.project.common.core.util.SpringUtils;
import org.jim.core.packets.pub.consts.Command;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * @author WChao
 * @date 2018年3月9日 上午1:06:33
 */
@Deprecated
public class CommandConfigurationFactory {

    private static final Logger LOG = LoggerFactory.getLogger(CommandConfigurationFactory.class.getName());

    private static final String DEFAULT_CLASSPATH_CONFIGURATION_FILE = "command.properties";

    /**
     * Constructor.
     */
    private CommandConfigurationFactory() {

    }

    /**
     * Configures a bean from an property file.
     */
//    public static List<CommandConfiguration> parseConfiguration(final File file) throws Exception {
//        if (file == null) {
//            throw new Exception("Attempt to configure command from null file.");
//        }
//        LOG.debug("Configuring command from file: {}", file);
//        List<CommandConfiguration> configurations = null;
//        InputStream input = null;
//        try {
//            input = new BufferedInputStream(new FileInputStream(file));
//            configurations = parseConfiguration(input);
//        } catch (Exception e) {
//            throw new Exception("Error configuring from " + file + ". Initial cause was " + e.getMessage(), e);
//        } finally {
//            try {
//                if (input != null) {
//                    input.close();
//                }
//            } catch (IOException e) {
//                LOG.error("IOException while closing configuration input stream. Error was " + e.getMessage());
//            }
//        }
//        return configurations;
//    }

    /**
     * Configures a bean from an property file available as an URL.
     */
//    public static List<CommandConfiguration> parseConfiguration(final URL url) throws Exception {
//        LOG.debug("Configuring command from URL: {}", url);
//        List<CommandConfiguration> configurations;
//        InputStream input = null;
//        try {
//            input = url.openStream();
//            configurations = parseConfiguration(input);
//        } catch (Exception e) {
//            throw new Exception("Error configuring from " + url + ". Initial cause was " + e.getMessage(), e);
//        } finally {
//            try {
//                if (input != null) {
//                    input.close();
//                }
//            } catch (IOException e) {
//                LOG.error("IOException while closing configuration input stream. Error was " + e.getMessage());
//            }
//        }
//        return configurations;
//    }

    /**
     * Configures a bean from an property file in the classpath.
     */
    public static List<CommandConfiguration> parseConfiguration() throws Exception {

        //update by linjie (加载不到command.properties)
//        URL url = ResourceUtil.getResource(DEFAULT_CLASSPATH_CONFIGURATION_FILE);
//
//
//        ClassLoader standardClassloader = Thread.currentThread().getContextClassLoader();
//        if (url == null && standardClassloader != null) {
//            url = standardClassloader.getResource(DEFAULT_CLASSPATH_CONFIGURATION_FILE);
//        }
//        if (url == null) {
//            url = CommandConfigurationFactory.class.getResource(DEFAULT_CLASSPATH_CONFIGURATION_FILE);
//        }
//        if (url != null) {
//            LOG.debug("Configuring command from command.properties found in the classpath: " + url);
//        } else {
//            LOG.warn("No configuration found. Configuring command from command.properties "
//                    + " found in the classpath: {}", url);
//
//        }
//        List<CommandConfiguration> configurations = parseConfiguration(url);

//
//        //增加了一个使用注解配置handler的方法开始
//        String packages = PropUtil.get("jim.handler.scan.packages");
//        List<String> handlerPackages = new ArrayList<>();
//        handlerPackages.add("org.jim.server.comman");
//        if (StrUtil.isNotBlank(packages)) {
//            handlerPackages.addAll(Arrays.asList(packages.split(",")));
//        }
//        for (String pkg : handlerPackages) {
//            Reflections reflections = new Reflections(pkg);
//            Set<Class<?>> classesList = reflections.getTypesAnnotatedWith(CommandHandler.class);
//            CommandConfiguration config;
//            CommandHandler anno;
//            for (Class classes : classesList) {
//                anno = AnnotationUtil.getAnnotation(classes, CommandHandler.class);//# classes.getClass().getAnnotation(CommandHandler.class);
//                config = new CommandConfiguration();
//                Command command = anno.cmd();
//                config.setCmd(command.getNumber());
//                config.setCmdHandler(classes.getName());
//                config.setCmdProcessors(Arrays.asList(anno.cmdProcessors()));
//                config.setCmdProcessorClasses(Arrays.asList(anno.cmdProcessorClasses()));
//                configurations.add(config);
//            }
//        }

        List<CommandConfiguration> configurations=new ArrayList<>();
        Map<String, CmdHandler> cmdHandlerMap = SpringUtils.getApplicationContext().getBeansOfType(CmdHandler.class);

       // Map<String, Object> beans = SpringUtils.getApplicationContext().getBeansWithAnnotation(CommandHandler.class);

        CommandHandler anno;
        CommandConfiguration config;
        for(CmdHandler obj:cmdHandlerMap.values()){
            anno = AnnotationUtil.getAnnotation(obj.getClass(), CommandHandler.class);
            config = new CommandConfiguration();
            Command command = anno.cmd();
            config.setCmd(command.getNumber());
            config.setCmdHandler(obj);
           // config.setCmdProcessors(Arrays.asList(anno.cmdProcessors()));
            config.setCmdProcessorClasses(Arrays.asList(anno.cmdProcessorClasses()));
            configurations.add(config);
        }

        //增加handler的方法结束
        return configurations;
    }

    /**
     * Configures a bean from an property input stream.
     */
//    public static List<CommandConfiguration> parseConfiguration(final InputStream inputStream) throws Exception {
//
//        LOG.debug("Configuring command from InputStream");
//
//        List<CommandConfiguration> configurations = new ArrayList<CommandConfiguration>();
//        try {
//            Properties props = new Properties();
//            props.load(inputStream);
//            for (String key : props.stringPropertyNames()) {
//                configurations.add(new CommandConfiguration(key, props));
//            }
//        } catch (Exception e) {
//            throw new Exception("Error configuring from input stream. Initial cause was " + e.getMessage(), e);
//        }
//        return configurations;
//    }
}
